package com.easylinkin.linkappapi.iaqi.service.impl;

import com.easylinkin.linkappapi.common.iaqi.IaqiUtil;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.device.entity.vo.DeviceQueryVo;
import com.easylinkin.linkappapi.elasticsearch.service.impl.EsServiceImpl;
import com.easylinkin.linkappapi.iaqi.config.IaqiConfig;
import com.easylinkin.linkappapi.iaqi.config.IaqiConfigUtil;
import com.easylinkin.linkappapi.iaqi.entity.IaqiStatistic;
import com.easylinkin.linkappapi.iaqi.service.IaqiService;
import com.easylinkin.linkappapi.iaqi.service.IaqiStatisticService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 空气质量等级
 * </p>
 *
 * @author TongJie
 * @since 2022-06-24
 */
@Service
@Slf4j
public class IaqiServiceImpl implements IaqiService {


    @Resource
    private EsServiceImpl esService;
    @Resource
    private IaqiStatisticService iaqiStatisticService;
    @Autowired
    private RedissonClient redisson;
    @Resource
    private IaqiConfigUtil iaqiConfigUtil;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    /**
     * 需要统计的租户id
     */
//    private final String[] tenantIds = {"405cd2c8633ecbee1c5f61c4a87c9019"};
//    /**
//     * 需要统计的属性
//     */
//    private final String[] attrs = {"pm10", "pm25"};
//    /**
//     * 需要统计的设备编号
//     */
//    private final String[] deviceCodes = {"40194860"};


    @Scheduled(cron = "0 20 2 * * ?")
    public void schedule() {
        try {
            log.info("start execute iaqi task 定时任务................ start");
            saveIaqiStatistic(Calendar.getInstance());
            log.info("start execute iaqi task 定时任务................ end");
        }catch (Exception e){
            log.error("start execute iaqi task 定时任务................ error",e);
        }
    }

    public void saveIaqiStatistic(Calendar calendar) {
        RLock redissonLock = redisson.getLock("synchronizationDeviceData_lock");
        if (redissonLock.tryLock()) {
            try {
                List<IaqiConfig> configs = iaqiConfigUtil.getConfigs();
                for (IaqiConfig config : configs) {
                    try {
                        Calendar calendar1 = Calendar.getInstance();
                        calendar1.setTime(calendar.getTime());
                        IaqiStatistic iaqiStatistic = getIaqiStatistic(config, calendar1);
                        if (iaqiStatistic != null) {
                            iaqiStatisticService.saveOne(iaqiStatistic);
                        }
                    } catch (Exception e) {
                        log.error("保存空气质量等级出错了", e);
                    }
                    log.info("start execute iaqi task ................ end");
                }
            } catch (Exception e) {
                log.error("com.easylinkin.linkappapi.iaqi.service.impl.IaqiServiceImpl.schedule error", e);
            } finally {
                redissonLock.unlock();
            }
        }
    }

    private IaqiStatistic getIaqiStatistic(IaqiConfig config) {
        return getIaqiStatistic(config, Calendar.getInstance());
    }

    private IaqiStatistic getIaqiStatistic(IaqiConfig config, Calendar calendar) {
        String tenantId = config.getTenantId();
        List<String> deviceCodes = config.getDeviceCodes();
        List<String> attrs = config.getAttrs();
        String pm10key = attrs.get(0);
        String pm25key = attrs.get(1);

        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        String end = DateUtil.getYYYYMMDDHHMMSSDate(calendar.getTime());
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(calendar.getTime());
        calendar1.add(Calendar.DATE, -1);
        String start = DateUtil.getYYYYMMDDHHMMSSDate(calendar1.getTime());

        DeviceQueryVo deviceQueryVo = new DeviceQueryVo();
        deviceQueryVo.setQueryTimeEnd(end);
        deviceQueryVo.setQueryTimeStart(start);
        deviceQueryVo.setDeviceCodeList(deviceCodes);
        deviceQueryVo.setTenantId(tenantId);
        IaqiStatistic iaqiStatistic10 = getIaqiStatistic(deviceQueryVo, pm10key);
        IaqiStatistic iaqiStatistic25 = getIaqiStatistic(deviceQueryVo, pm25key);
        if (iaqiStatistic10 == null && iaqiStatistic25 == null) {
            return null;
        }
        int pm10 = iaqiStatistic10 != null && iaqiStatistic10.getStatisticValue() != null ? iaqiStatistic10.getStatisticValue().intValue() : 0;
        int pm25 = iaqiStatistic25 != null && iaqiStatistic25.getStatisticValue() != null ? iaqiStatistic25.getStatisticValue().intValue() : 0;
        int level = IaqiUtil.getIaqiLevel(pm10, pm25);
        int pm = IaqiUtil.getIaqiValueByPm(pm10, pm25);

        IaqiStatistic iaqiStatistic = new IaqiStatistic();
        iaqiStatistic.setCreateTime(new Date());
        iaqiStatistic.setTenantId(tenantId);
        Date time = null;
        if (iaqiStatistic10 != null && iaqiStatistic10.getStatisticTime() != null) {
            time = iaqiStatistic10.getStatisticTime();
        } else if (iaqiStatistic25 != null && iaqiStatistic25.getStatisticTime() != null) {
            time = iaqiStatistic25.getStatisticTime();
        }
        iaqiStatistic.setStatisticTime(time);
        iaqiStatistic.setStatisticValue((double) pm);
        iaqiStatistic.setLevel(level);
        return iaqiStatistic;
    }

    private IaqiStatistic getIaqiStatistic(DeviceQueryVo deviceQueryVo, String attr) {
        deviceQueryVo.setHasAttrs(new ArrayList<>(Collections.singleton(attr)));
        List<IaqiStatistic> list = esService.queryPeriodTimeAvgGroupByTime(deviceQueryVo);
        if (list == null || list.size() == 0) {
            log.info("查询空气平均结果为空");
            return null;
        } else if (list.size() > 1) {
            log.info("查询空气平均结果大于1" + list.size());
        }
        IaqiStatistic iaqiStatistic = list.get(0);
        return iaqiStatistic;
    }


    public Integer getCurrentIaqiValue() {
        Double value = 0d;
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        List<IaqiConfig> configs = iaqiConfigUtil.getConfigs();
        if (configs != null && configs.size() > 0) {
            configs = configs.stream().filter((e) -> e.getTenantId().equals(tenantId)).collect(Collectors.toList());
            if (configs.size() > 0) {
                IaqiStatistic iaqiStatistic = getIaqiStatistic(configs.get(0));
                if (iaqiStatistic != null) {
                    value = iaqiStatistic.getStatisticValue();
                    if (value != null) {
                        return value.intValue();
                    }
                }
            }
        }
        return 0;
    }
}

